<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片格式转换</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@latest/css/pico.min.css">
    <script src="https://cdn.jsdelivr.net/npm/vue@3.2.29/dist/vue.global.js"></script>
    <style type="text/css">
        header {
            border-bottom: 1px solid #e5e5e5;
            margin-bottom: 30px;
        }
    </style>
</head>



<body>
    <div id="app">
        <header>
            <nav class="container-fluid">
                <ul>
                    <li><strong>图片格式转换</strong></li>
                </ul>
                <ul>
                </ul>
            </nav>
        </header>
        <main class="container">
            <div style="display: grid;grid-template-columns: 15em 5em;column-gap: 10px;">
                <input type="file" ref="file" accept="image/*" multiple>
                <button @click="fileupload" style="width: 5em;">转换</button>
            </div>
            <select v-model="selected">
                <option disabled value="">选择需要转换到的格式</option>
                <option>png</option>
                <option>jpeg</option>
                <option>webp</option>
            </select>
            <label>
                质量 0-1 当选择不为 png 时有效
                <input type="number" v-model="quality">
            </label>
            <p v-if="errmsg" style="color: red;">{{ errmsg }}</p>
            <div style="display: grid;grid-template-columns: 8em 5em;column-gap: 10px;">
                <button v-if="imgs.length" @click="alldownload">全部下载</button>
                <button v-if="imgs.length" @click="clean">清空</button>
            </div>

            <div class="imgs" v-if="imgs.length"
                style="display: grid;grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));gap: 15px;align-items:center;padding-bottom: 20px;">
                <div v-for="(img, index) in imgs" :key="index">
                    <img :src="img.url">
                    <span>{{ img.size / 1000 / 1000 }}MB</span>
                </div>
            </div>
        </main>
    </div>
</body>

<script type="text/javascript">
    Vue.createApp({
        setup(props, context) {
            const errmsg = Vue.ref('');
            const file = Vue.ref(null);
            const selected = Vue.ref('');
            const quality = Vue.ref(0.8);
            const imgs = Vue.ref([]);

            async function fileupload() {
                const f = file.value;
                errmsg.value = "";

                if (selected.value == "") {
                    errmsg.value = "请选择转换格式";
                    return;
                }

                if (f.files.length == 0) {
                    errmsg.value = "请选择文件";
                    return;
                }

                for (const v of f.files) {
                    if (v.type.indexOf('image') === -1) {
                        errmsg.value = "请选择图片文件";
                        return;
                    }
                    const u = URL.createObjectURL(v)
                    const b = await conver(selected.value, quality.value, u);
                    URL.revokeObjectURL(u);
                    const uu = URL.createObjectURL(b)

                    imgs.value.push({
                        url: uu,
                        ext: selected.value,
                        size: b.size
                    });
                }
            }

            function alldownload() {
                let i = 0
                for (const v of imgs.value) {
                    i++;
                    const a = document.createElement('a');
                    a.href = v.url;
                    let ext = v.ext
                    if (ext == "jpeg") {
                        ext = "jpg"
                    }
                    a.download = i + "." + ext;
                    a.click();
                }
            }

            function clean() {
                for (const v of imgs.value) {
                    URL.revokeObjectURL(v.url);
                }
                imgs.value = []
            }

            async function conver(f, q, url) {
                let canvas = document.createElement('canvas');
                let ctx = canvas.getContext('2d');
                let image = new Image();
                image.src = url;

                return new Promise((resolve, reject) => {
                    image.onload = () => {
                        canvas.width = image.width;
                        canvas.height = image.height;
                        if (f == "jpeg") {
                            ctx.fillStyle = '#ffffff';
                            ctx.fillRect(0, 0, canvas.width, canvas.height);
                        }
                        ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
                        canvas.toBlob((b) => {
                            resolve(b);
                        }, `image/${f}`, q)

                    }
                })
            }

            return {
                errmsg,
                file,
                selected,
                quality,
                imgs,
                fileupload,
                alldownload,
                clean
            }
        },
    }).mount('#app')


</script>

</html>